﻿using System;
using System.Collections.Generic;
using System.Threading;
using Comm.PublicClass;
using WsProtocol.IEC62056MDL;
using WsProtocol.IEC62056;
using WsProtocol.IEC62056.DLL;
using WsProtocol.PublicClass;
using System.Threading.Tasks;

namespace Wasion.HHU.Services
{
    public delegate void NextFramePostedDelegate(object testMeter, object anaPtl, ClientApduSel rwflag, string rwtype, int doflag, string errinfo);
    
    public class FunMeterMulti : FunMeterBase
    {
        public bool NeedHandShake = false;  //是否需要握手
        public NextFramePostedDelegate ShowUIResult = null;  //界面显示结果
        private List<TestMeter> selmeters = null;  //当前选中表
        public List<TestMeter> MeterLst
        {
            get { return selmeters; }
            set 
            {
                selmeters = value;
                BaseMeterLst.Clear();
                if (selmeters != null)
                    for (int i = 0; i < selmeters.Count; i++)
                        BaseMeterLst.Add((PtlBaseMeter)selmeters[i]);
            }
        }


        /// <summary>
        /// 根据传入协议得到对应的获取正确格式返回帧的委托
        /// </summary>
        /// <param name="ptltype">协议类别</param>
        /// <returns>获取正确格式帧的委托</returns>
        public CommProperty.EventGetReceive GetCorrectFrame()
        {
            try
            {
                return new CommProperty.EventGetReceive(new Analysis62056.TProtocol62056().GetFrameWithoutUpload);
            }
            catch (Exception e)
            {
                return null;
            }
        }


       
        #region 建立连接
        /// <summary>
        /// 执行建立连接
        /// </summary>
        /// <returns></returns>
        public int DoConnect(List<TestMeter> MeterLst, List<TestMeter> tmpMeterLst, SecurityPolicy SecurityOption, NextFramePostedDelegate NextFramePosted, ref string errinfo)
        {
            ShowUIResult = NextFramePosted;
            int rs = 0;

            NeedHandShake = true;  //每次建链接就要重新握手  shaunwang 2018-12-14

            if (SecurityOption != SecurityPolicy.无认证)
            {
                rs = MakeNoAuthConnect(MeterLst, tmpMeterLst, ref errinfo);
                if (rs < 0)
                    return rs;

            }

            //预连接角色不需要进行下一步   shaunwang 2019-08-02
            if (PubFunc62056.CheckPreConnClient(MeterLst[0].Meter62056.MTRole.RoleClientAddr))
                return rs;

            rs = MakeDLLConnect(MeterLst, ref errinfo);
            if (rs < 0)
                errinfo = "建立链路层连接失败，错误原因：" + errinfo;
            else
            {
                rs = MakeCosemConnect(MeterLst, ref errinfo);
                if (rs < 0)
                    errinfo = "建立应用层连接失败，错误原因：" + errinfo;
                else 
                    if (SecurityOption != SecurityPolicy.无认证)
                    {
                        rs = MakeCosemHLSAuthen(MeterLst, ref errinfo);
                        if (rs < 0)
                            errinfo = "建立应用连接时身份验证失败，错误原因：" + errinfo;
                    }
            }
            return rs;
        }



        /// <summary>
        /// 建立链路层连接
        /// </summary>
        /// <param name="meterlst"></param>
        /// <param name="ConnectMechanismInfo"></param>
        /// <param name="errinfo"></param>
        /// <returns></returns>
        public int MakeDLLConnect(List<TestMeter> meterlst, ref string errinfo)
        {
            int rs = 1;
            try
            {
                if (meterlst.Count == 0)
                    return rs;
                this.MeterLst = meterlst;
                List<TestMeter> tmplst = new List<TestMeter>();
                for (int m = 0; m < meterlst.Count; m++)
                {
                    //Application.DoEvents();
                    if (!string.IsNullOrEmpty(meterlst[m].ErrInfo) || !string.IsNullOrEmpty(meterlst[m].Meter62056.udpCAddr)) //47协议UDP模式不建链路层链接
                        continue;
                    meterlst[m].ObAttrLst = PubFunc62056.GetDLLConnectAttr(meterlst[m].Meter62056, ref errinfo);
                    //meterlst[m].FCurrent = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
                    tmplst.Add(meterlst[m]);
                }
                StopOperating(false);
                NextFramePostedDelegate NextFramePosted = new NextFramePostedDelegate(DoAfterDLConnect);
                if (ShowUIResult != null)
                    NextFramePosted += ShowUIResult;
                rs = RWOneDataFromObAttr(tmplst, EnuFrameType.SNRM, ClientApduSel.DLConnectRequest, "", true, NextFramePosted);
                
            }
            catch (Exception ex)
            {
                errinfo = ex.Message;
                rs = -1;
            }
            return rs;
        }


        /// <summary>
        /// 建立链路层连接后执行相关操作
        /// </summary>
        /// <param name="testMeter"></param>
        /// <param name="anaPtl"></param>
        /// <param name="rwflag"></param>
        /// <param name="rwtype"></param>
        /// <param name="errinfo"></param>
        private void DoAfterDLConnect(object testMeter, object anaPtl, ClientApduSel rwflag, string rwtype, int doflag, string errinfo)
        {
            Analysis62056.TProtocol62056 orderptl = (Analysis62056.TProtocol62056)anaPtl;
            TestMeter resmeter = (TestMeter)testMeter;
            if (string.IsNullOrEmpty(errinfo))
            {
                NeedHandShake = false;  //链路层链接正确之后认为握手成功  shaunwang 2018-12-14
                
                CosemObject OIobj = orderptl.ptlformat.Apdu.OIList[0];
                //链路层连接返回NOK时，才会有新的用户信息返回，用返回的用户信息更新表档案，否则表示接受发送的用户信息，不用更新
                if (OIobj.result == ((int)DLLConnResult.NOK).ToString())
                {
                    //"发送最大信息域长度";
                    resmeter.Meter62056.SendMaxSize = OIobj.DataNode.eleNodeList[0].ReadValue;

                    //"接收最大信息域长度";
                    resmeter.Meter62056.RecMaxSize = OIobj.DataNode.eleNodeList[1].ReadValue;

                    //"发送窗口尺寸";
                    resmeter.Meter62056.SendMaxWindow = OIobj.DataNode.eleNodeList[2].ReadValue;

                    // "接收窗口尺寸";
                    resmeter.Meter62056.RecMaxWindow = OIobj.DataNode.eleNodeList[3].ReadValue;

                    OIobj.result = ((int)DLLConnResult.OK).ToString();
                }
            }
            else
            {
                resmeter.ErrInfo = errinfo;
            }
        }

        

        //无任何认证且客户地址为最低级密码的特定地址的链路层及应用层连接
        public int MakeNoAuthConnect(List<TestMeter> meterlst, List<TestMeter> tmpmeterlst, ref string errinfo)
        {
            int rs = 1;
            try
            {
                if (meterlst.Count == 0)
                    return rs;
                this.MeterLst = meterlst;
                //List<TestMeter> tmplst = new List<TestMeter>();

                for (int m = meterlst.Count - 1; m >= 0; m--)
                {
                    //Application.DoEvents();
                    if (!string.IsNullOrEmpty(meterlst[m].ErrInfo))
                    {
                        meterlst.Remove(meterlst[m]);
                        continue;
                    }

                    TestMeter aMeter = meterlst[m].Copy();
                    aMeter.MeterCommAddr = meterlst[m].MeterCommAddr;
                    aMeter.Meter62056.ContextName = RequirContext.LN_NoCipher;
                    aMeter.Meter62056.SecurityModeExpand = AuthenticationExpand.NoAuth;
                    aMeter.Meter62056.MTRole.RoleClientAddr = "16";//公共客户端,COSEM客户机可以最低安全级访问表计

                    if (!string.IsNullOrEmpty(aMeter.Meter62056.udpCAddr))  //47协议
                        aMeter.Meter62056.udpCAddr = MyConvert.DecToHex("16", 4);

                    tmpmeterlst.Add(aMeter);
                }

                rs = MakeDLLConnect(tmpmeterlst, ref errinfo);
                if (rs < 0) {
                    return rs;
                }

                rs = MakeCosemConnect(tmpmeterlst, ref errinfo);
                if (rs < 0)
                {
                    return rs;
                }
                rs = GetFrameCount(tmpmeterlst, ref errinfo);
                if (rs < 0)
                {
                    return rs;
                }
                for (int m = 0; m < meterlst.Count; m++)
                {
                    meterlst[m].Meter62056.IC = tmpmeterlst[m].Meter62056.IC;
                }

                if (!string.IsNullOrEmpty(tmpmeterlst[0].Meter62056.udpCAddr))  //47协议断开
                    rs = ACSE_Disconnect(tmpmeterlst, ref errinfo);
                else  //正常断开
                    rs = Disconnect(tmpmeterlst, ref errinfo);

            }
            catch (Exception ex)
            {
                errinfo = ex.Message;
                rs = -1;
            }
            return rs;
        }

        /// <summary>
        /// 在建立公共链接后取得各个表的帧计数器
        /// </summary>
        /// <param name="meterlst"></param>
        /// <param name="errinfo"></param>
        /// <returns></returns>
        public int GetFrameCount(List<TestMeter> meterlst, ref string errinfo)
        {
            int rs = 1;
            try
            {
                if (meterlst.Count == 0)
                    return rs;
                this.MeterLst = meterlst;
                List<TestMeter> tmplst = new List<TestMeter>();
                for (int m = 0; m < meterlst.Count; m++)
                {
                    //Application.DoEvents();
                    if (!string.IsNullOrEmpty(meterlst[m].ErrInfo))
                        continue;
                    
                    meterlst[m].ObAttrLst = PubFunc62056.GetFrameCountAttr(meterlst[m].Meter62056, ref errinfo);
                    tmplst.Add(meterlst[m]);
                }
                StopOperating(false);
                NextFramePostedDelegate NextFramePosted = new NextFramePostedDelegate(DoAfterGetFrameCount);
                if (ShowUIResult != null)
                    NextFramePosted += ShowUIResult;
                rs = RWOneDataFromObAttr(tmplst, EnuFrameType.I, ClientApduSel.GETRequest, GetRRMode.GetNormal.ToString(), true, NextFramePosted);

            }
            catch (Exception ex)
            {
                errinfo = ex.Message;
                rs = -1;
            }
            return rs;
        }


        private void DoAfterGetFrameCount(object testMeter, object anaPtl, ClientApduSel rwflag, string rwtype, int doflag, string errinfo)
        {
            Analysis62056.TProtocol62056 orderptl = (Analysis62056.TProtocol62056)anaPtl;
            TestMeter resmeter = (TestMeter)testMeter;
            if (string.IsNullOrEmpty(errinfo))
            {
                CosemObject OIobj = orderptl.ptlformat.Apdu.OIList[0];
                if (OIobj.result != "0")
                {
                    resmeter.ErrInfo = OIobj.result;
                    return;
                }

                resmeter.Meter62056.IC = Convert.ToUInt32(OIobj.DataNode.ReadValue);                  
            }
            else
            {
                resmeter.ErrInfo = errinfo;  
            }
        }


        public int MakeCosemConnect(List<TestMeter> meterlst, ref string errinfo)
        {
            int rs = 1;
            try
            {
                if (meterlst.Count == 0)
                    return rs;
                this.MeterLst = meterlst;
                List<TestMeter> tmplst = new List<TestMeter>();
                for (int m = 0; m < meterlst.Count; m++)
                {                    
                    //Application.DoEvents();
                    if (!string.IsNullOrEmpty(meterlst[m].ErrInfo))
                        continue;

                    meterlst[m].Meter62056.ResetCount();
                    meterlst[m].ObAttrLst = PubFunc62056.GetCosemConnectAttr(meterlst[m].Meter62056, ref errinfo);
                    tmplst.Add(meterlst[m]);
                }
                StopOperating(false);
                NextFramePostedDelegate NextFramePosted = new NextFramePostedDelegate(DoAfterCosemConnect);
                if (ShowUIResult != null)
                    NextFramePosted += ShowUIResult;
                rs = RWOneDataFromObAttr(tmplst, EnuFrameType.I, ClientApduSel.ConnectRequest, "",true, NextFramePosted);

            }
            catch (Exception ex)
            {
                errinfo = ex.Message;
                rs = -1;
            }
            return rs;
        }

        /// <summary>
        /// 建立应用层连接后执行相关操作
        /// </summary>
        /// <param name="testMeter"></param>
        /// <param name="anaPtl"></param>
        /// <param name="rwflag"></param>
        /// <param name="rwtype"></param>
        /// <param name="errinfo"></param>
        private void DoAfterCosemConnect(object testMeter, object anaPtl, ClientApduSel rwflag, string rwtype, int doflag, string errinfo)
        {
            Analysis62056.TProtocol62056 orderptl = (Analysis62056.TProtocol62056)anaPtl;
            TestMeter resmeter = (TestMeter)testMeter;
            if (string.IsNullOrEmpty(errinfo))
            {
                CosemObject OIobj = orderptl.ptlformat.Apdu.OIList[0];
                if (OIobj.result != "0") return;

                for (int i = 0; i < OIobj.DataNode.eleNodeList.Count; i++)
                {
                    ElementData eleobj = OIobj.DataNode.eleNodeList[i];
                    switch (i)
                    {
                        case 0: //"Application-context-name"
                            resmeter.Meter62056.ContextName = eleobj.ReadValue == null ? resmeter.Meter62056.ContextName : (RequirContext)int.Parse(eleobj.ReadValue);
                            break;
                        case 1: //"MechanismName"; 认证级别和密码,有时返回不存在，则不更新原表计里的信息
                            if (string.IsNullOrEmpty(eleobj.ReadValue))
                            {
                                if (resmeter.Meter62056.SecurityMode >= Authentication.HLS)
                                {
                                    resmeter.ErrInfo = "高级认证未返回认证信息";
                                    OIobj.result = resmeter.ErrInfo;// ((int)DLLConnResult.NOK).ToString();
                                    return;
                                }
                                else
                                    continue;
                            }
                            resmeter.Meter62056.SecurityMode = (Authentication)int.Parse(eleobj.ReadValue);
                            string AuthValue = eleobj.eleNodeList[0].ReadValue;
                            if (!string.IsNullOrEmpty(AuthValue))
                                resmeter.Meter62056.EncParams.StoC = AuthValue;//高级认证返回的已加密的数据

                            break;
                        case 2: //"AA_UserInfo";
                            resmeter.Meter62056.ProConform = eleobj.eleNodeList[0].ReadValue;

                            if (eleobj.eleNodeList[1].ReadValue != "0")
                                resmeter.Meter62056.APDUSize = eleobj.eleNodeList[1].ReadValue;
                            else
                                resmeter.Meter62056.APDUSize = resmeter.Meter62056.APDUSize == "0" ? PtlConsts.defApduSize.ToString() : resmeter.Meter62056.APDUSize;
                            resmeter.Meter62056.AppProVersion = eleobj.eleNodeList[3].ReadValue;
                            break;

                    }
                }
                OIobj.result = ((int)DLLConnResult.OK).ToString();

                // resmeter.Identity = true; // 建立应用连接相当于身份认证
            }
            else
            {
                resmeter.ErrInfo = errinfo;
            }

        }

        /// <summary>
        /// 第15类对象的方法1 reply_to HLS_authentication
        /// </summary>
        /// <param name="meterlst"></param>
        /// <param name="errinfo"></param>
        /// <returns></returns>
        public int MakeCosemHLSAuthen(List<TestMeter> meterlst, ref string errinfo)
        {
            int rs = 1;
            try
            {
                this.MeterLst = meterlst;
                List<TestMeter> tmplst = new List<TestMeter>();
                for (int m = 0; m < meterlst.Count; m++)
                {
                    //Application.DoEvents();
                    if (meterlst[m].Meter62056.SecurityMode < Authentication.HLS || !string.IsNullOrEmpty(meterlst[m].ErrInfo))
                        continue;

                    meterlst[m].ObAttrLst = PubFunc62056.GetHLSAuthenAttr(meterlst[m].Meter62056, ref errinfo);
                    tmplst.Add(meterlst[m]);
                }
                StopOperating(false);
                NextFramePostedDelegate NextFramePosted = new NextFramePostedDelegate(DoAfterCosemHLSAuthen);
                if (ShowUIResult != null)
                    NextFramePosted += ShowUIResult;
                rs = RWOneDataFromObAttr(tmplst, EnuFrameType.I, ClientApduSel.ActionRequest, ActionRRMode.ActionNormal.ToString(), true, NextFramePosted);

            }
            catch (Exception ex)
            {
                errinfo = ex.Message;
                rs = -1;
            }
            return rs;
        }

        

        /// <summary>
        /// 高级认证后执行相关操作
        /// </summary>
        /// <param name="testMeter"></param>
        /// <param name="anaPtl"></param>
        /// <param name="rwflag"></param>
        /// <param name="rwtype"></param>
        /// <param name="errinfo"></param>
        private void DoAfterCosemHLSAuthen(object testMeter, object anaPtl, ClientApduSel rwflag, string rwtype, int doflag, string errinfo)
        {
            Analysis62056.TProtocol62056 orderptl = (Analysis62056.TProtocol62056)anaPtl;
            TestMeter resmeter = (TestMeter)testMeter;
            if (string.IsNullOrEmpty(errinfo))
            {
                CosemObject OIobj = orderptl.ptlformat.Apdu.OIList[0];

                if (OIobj.result != "0") return;

                string CtoSRandom = OIobj.DataNode.FrameValue;//对帧里面数据加密
                resmeter.Meter62056.EncParams.PlaintData = CtoSRandom;
                resmeter.Meter62056.EncParams.GCM_AESEncrypt(SecurityPolicy.需认证,false, ref errinfo);//加密第3步返回的数据
                if (string.IsNullOrEmpty(errinfo))//f(CtoS) 正确
                { 
                   //通过验证
                }
                
               
            }
            else
            {
                resmeter.ErrInfo = errinfo;
            }

        }

        

        public int Disconnect(List<TestMeter> meterlst, ref string errinfo)
        {
            int rs = 1;
            try
            {
                if (meterlst.Count == 0)
                    return rs;
                List<TestMeter> tmplst = new List<TestMeter>();
                for (int m = 0; m < meterlst.Count; m++)
                {
                    //Application.DoEvents();
                    if (!string.IsNullOrEmpty(meterlst[m].ErrInfo))
                        continue;

                    //生成要读取对象的列表
                    List<ProObAttr> AttrLst = new List<ProObAttr>();

                    //应用连接对象
                    ProObject proObject = new ProObject();
                    proObject.checkState = CheckState.Checked;
                    proObject.ObName = "";

                    ProObAttr connAttr = new ProObAttr();
                    connAttr.proObject = proObject;
                    connAttr.checkState = CheckState.Checked;
                    connAttr.AttrMth = AttrType.属性;
                    connAttr.ProName = "断开链路层_连接";
                    proObject.AttrLst.Add(connAttr);
                    AttrLst.Add(connAttr);


                    meterlst[m].ObAttrLst = AttrLst;

                    tmplst.Add(meterlst[m]);
                }
                StopOperating(false);
                NextFramePostedDelegate NextFramePosted = new NextFramePostedDelegate(DoAfterDisconnect);
                if (ShowUIResult != null)
                    NextFramePosted += ShowUIResult;
                rs = RWOneDataFromObAttr(tmplst, EnuFrameType.DISC, ClientApduSel.DLReleaseRequest, "", true, NextFramePosted);

            }
            catch (Exception ex)
            {
                errinfo = ex.Message;
                rs = -1;
            }
            return rs;
        }

        public int ACSE_Disconnect(List<TestMeter> meterlst, ref string errinfo)  //应用层断开连接
        {
            int rs = 1;
            try
            {
                if (meterlst.Count == 0)
                    return rs;
                List<TestMeter> tmplst = new List<TestMeter>();
                for (int m = 0; m < meterlst.Count; m++)
                {
                    //Application.DoEvents();
                    if (!string.IsNullOrEmpty(meterlst[m].ErrInfo))
                        continue;

                    meterlst[m].ObAttrLst = PubFunc62056.GetCosemDisConnectAttr(meterlst[m].Meter62056, ref errinfo);

                    tmplst.Add(meterlst[m]);
                }
                StopOperating(false);
                NextFramePostedDelegate NextFramePosted = null;// new NextFramePostedDelegate(DoAfterACSEDisconnect);
                if (ShowUIResult != null)
                    NextFramePosted += ShowUIResult;
                rs = RWOneDataFromObAttr(tmplst, EnuFrameType.I, ClientApduSel.ReleaseRequest, "", true, NextFramePosted);

            }
            catch (Exception ex)
            {
                errinfo = ex.Message;
                rs = -1;
            }
            return rs;
        }

        // <summary>
        // 断开应用连接后执行相关操作
        // </summary>
        // <param name="testMeter"></param>
        // <param name="anaPtl"></param>
        // <param name="rwflag"></param>
        // <param name="rwtype"></param>
        // <param name="errinfo"></param>
        private void DoAfterDisconnect(object testMeter, object anaPtl, ClientApduSel rwflag, string rwtype, int doflag, string errinfo)
        {
            //TestMeter resmeter = (TestMeter)testMeter;
            //resmeter.Identity = false; 
        }
        #endregion

        /// <summary>
        /// 只生成APDU中纯数据部分
        /// </summary>
        /// <param name="obattr"></param>
        /// <returns></returns>
        public  string GetObAttrFormatValue(ProObAttr obattr,int ApduFlag)
        {
          
            string orderApdu = "";
            try
            {
                TestMeter meter = new TestMeter();
                //操作方式显示

                #region 生成APDU中纯数据部分

                string errorinfo = string.Empty;
                List<ProObAttr> AttrLst = new List<ProObAttr>();
                AttrLst.Add(obattr);
                Analysis62056.TProtocol62056 orderptl = new Analysis62056.TProtocol62056();  
                try
                {
                    errorinfo = string.Empty;

                    orderApdu = PubFunc62056.CreateOrderOrPayload(orderptl, EnuFrameType.I, meter.Meter62056, AttrLst, ClientApduSel.SETRequest, SetRRMode.SetNormal.ToString(), ApduFlag, ref errorinfo);
                   
                    if (errorinfo != string.Empty)// || neworder.orderlst == null || neworder.orderlst.Count == 0)
                    {
                        errorinfo = "生成Apdu纯数据失败:" + errorinfo;
                    }
                }
                catch (Exception ex)
                {
                }
                #endregion
            }

            finally
            {
            }
            return orderApdu;
        }

        /// <summary>
        /// 根据ObAttr读取数据
        /// </summary>
        /// <param name="meterlst">表计列表</param>
        /// <param name="RorW">R?  W?</param>
        /// <param name="rwflag"></param>
        /// <param name="rwtype"></param>
        /// <param name="scflag"></param>
        /// <param name="timetag">时间标签</param>
        /// <param name="ShowUI">是否需要在界面显示</param>
        /// <param name="NextFramePosted"></param>
        /// <returns></returns>
        public int RWOneDataFromObAttr(List<TestMeter> meterlst, EnuFrameType funC, ClientApduSel rwflag, string rwtype, bool ShowUI, NextFramePostedDelegate NextFramePosted)
        {
            return RWOneDataFromObAttr(meterlst, funC, rwflag, rwtype, ShowUI, true, NextFramePosted);
        }

        
        /// <summary>
        /// 根据ObAttr读取数据
        /// </summary>
        /// <param name="meterlst">表计列表</param>
        /// <param name="RorW">R?  W?</param>
        /// <param name="rwflag"></param>
        /// <param name="rwtype"></param>
        /// <param name="scflag"></param>
        /// <param name="timetag">时间标签</param>
        /// <param name="ShowUI">是否需要在界面显示</param>
        /// <param name="bsendorder">生成指令后是否发送，对于抄读后比对的情况，只需要组织参数，不需要先发送设置命令</param>
        /// <param name="NextFramePosted"></param>
        /// <returns></returns>
        public int RWOneDataFromObAttr(List<TestMeter> meterlst, EnuFrameType funC, ClientApduSel rwflag, string rwtype, bool ShowUI, bool bsendorder, NextFramePostedDelegate NextFramePosted)
        {
            int rs = 1;
            try
            {
                if (meterlst.Count == 0)
                    return rs;
                this.MeterLst = meterlst;

                List<CommConst.TOrdertype> orderlst = new List<CommConst.TOrdertype>();
                #region 生成指令部分
                for (int m = 0; m < meterlst.Count; m++)
                {
                    //Application.DoEvents();
                    //Thread.Sleep(1);
                    Task.Delay(1).Wait();
                    TestMeter ameter = meterlst[m];
                    //实例化一个指令类
                    CommConst.TOrdertype neworder = new CommConst.TOrdertype();

                    neworder.ptltype = (int)PtlType.IEC62056;
                    //下面给neworder赋值
                    string errorinfo = string.Empty;

                    //预连接角色不需要返回
                    if (PubFunc62056.CheckPreConnClient(ameter.Meter62056.MTRole.RoleClientAddr))
                    {
                        rwflag = ClientApduSel.Generalglocipher; //预连接用general服务
                        ameter.Meter62056.EncParams.Key_Set = 1; //表示用广播密钥加密
                        neworder.waitreturn = false;
                    }

                    List<ProObAttr> AttrLst = ameter.ObAttrLst;
                    if (funC == EnuFrameType.I)
                    {
                        ameter.Meter62056.EncParams.Key_Set = 0; //表示单播地址
                        if ((ameter.Meter62056.AddrLen == 2 && ameter.MeterCommAddr == PtlConsts.BrOBISCastAddr1.ToString()) ||
                            (ameter.Meter62056.AddrLen == 4 && ameter.MeterCommAddr == PtlConsts.BrOBISCastAddr2.ToString()))
                        {
                            funC = EnuFrameType.UI; //hxh 广播地址时发UI帧
                            ameter.Meter62056.EncParams.Key_Set = 1; //表示广播地址
                        }
                       // ameter.Meter62056.GetNewSendCount();  //获取新的发送计数器
                    }
                    
                    Analysis62056.TProtocol62056 anaptl = PubFunc62056.CreateAnaPtl(ameter.Meter62056, AttrLst, rwflag, rwtype, ref errorinfo);  //用于解析
                    if (errorinfo != string.Empty)
                    {
                        errorinfo = "生成解析类失败:" + errorinfo;

                        if (NextFramePosted != null && ShowUI)
                            NextFramePosted(ameter, anaptl, rwflag, rwtype, -1, errorinfo);
                        neworder.Fail(false, errorinfo);
                        ameter.ErrInfo = errorinfo;
                        continue;
                    }

                    try
                    {
                        

                        errorinfo = string.Empty;
                        Analysis62056.TProtocol62056 orderptl = new Analysis62056.TProtocol62056();  //用于生成指令
                        //DateTime atime = DateTime.Now;
                        string orderstr = PubFunc62056.CreateOrder(orderptl, funC, ameter.Meter62056, AttrLst, rwflag, rwtype, ref errorinfo);
                        // TimeSpan ts = DateTime.Now - atime;
                        // int aa = ts.Milliseconds;
                        ameter.Meter62056.SendCount = orderptl.SSS;//hxh 生成命令发送计数器可能有变化
                        anaptl.SSS = orderptl.SSS; //解析后会把解析对象的SSS赋给表的计数器，为了保证任何时候都统一



                        neworder.orderlst = new List<string>(orderstr.Split(new char[]{','}, StringSplitOptions.RemoveEmptyEntries));


                        neworder.OrderName = orderptl.ptlinfo.DataName;

                        if (errorinfo != string.Empty || neworder.orderlst == null || neworder.orderlst.Count == 0)
                        {
                            errorinfo = "生成指令失败:" + errorinfo;

                            if (NextFramePosted != null && ShowUI)
                                NextFramePosted(ameter, anaptl, rwflag, rwtype, -1, errorinfo);
                            neworder.Fail(false, errorinfo);
                            ameter.ErrInfo = errorinfo;
                            continue;
                        }


                        //Encryption encryption = ameter.Meter62056.EncParams;
                        ////if ((encryption.ContextName == RequirContext.LN_Cipher || encryption.apduAuth >= Authentication.HLS)
                        ////    && encryption.securityPolicy != SecurityPolicy.Nothing)
                        //if (encryption.IfEncrypt() && !string.IsNullOrEmpty(encryption.PlaintData))
                        //{
                        //    neworder.orderinfo = "加密前数据:")
                        //                       + PubFunction.SplitStr(encryption.PlaintData);
                        //}


                        string realdata = orderptl.GetRealData();
                        if (!string.IsNullOrEmpty(realdata))
                        {
                            neworder.orderinfolst = new List<string>(realdata.Split(new char[]{','}, StringSplitOptions.RemoveEmptyEntries));
                            for (int i = 0; i < neworder.orderinfolst.Count; i++ )
                                neworder.orderinfolst[i] = "加密前数据:"
                                                         + PubFunction.SplitStr(neworder.orderinfolst[i]);
                            neworder.orderinfo = neworder.orderinfolst[0];
                        }
                        else
                            neworder.orderinfo = string.Empty;

                        neworder.realorder = neworder.orderlst[0];
                        neworder.order = neworder.realorder;
                        neworder.meterObj = ameter;  //
                        neworder.fmeterid = ameter.MeterID;
                        neworder.address = ameter.MeterCommAddr;
                        neworder.waitreturn = true;

                        

                        neworder.waitreturn = orderptl.NeedReturn();  //判断是否返回方法已封装到底层
                        
                        neworder.MeterSNo = ameter.SNO;  //表位
                        neworder.MACAddr = ameter.CommInfo.MACAddr;
                        neworder.AnaPtl = anaptl;

                        if (string.IsNullOrEmpty(ameter.Meter62056.udpCAddr)) //47协议UDP模式时无法取合法帧
                            neworder.GetCorrectFrame = GetCorrectFrame();

                        neworder.order = CommManager.GetWakeChar() + neworder.order + CommManager.GetDelayChar();  //增加前导符
                        neworder.DoAfterAnalysis = DoAfterAnalysis; //hxh 2018-5-28


                        //标志指令下发时是否需要重新握手  shaunwang 2018-12-14
                        neworder.ResetComm = funC == EnuFrameType.SNRM && rwflag == ClientApduSel.DLConnectRequest;// && NeedHandShake; //;

                        ameter.currorder = neworder;//wayne
                        //ameter.FCurrent = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
                        orderlst.Add(neworder);
                    }
                    catch (Exception ex)
                    {
                        errorinfo = "生成指令失败:" + ex;

                        if (NextFramePosted != null && ShowUI)
                            NextFramePosted(ameter, anaptl, rwflag, rwtype, -1, errorinfo);
                        neworder.Fail(false, errorinfo);
                        ameter.ErrInfo = errorinfo;
                        continue;
                    }
                    //ameter.Meter62056.ConfirmSendCount(); //确认发送计数器
                }
                #endregion
                if (!bsendorder)  //不需要发指令则直接退出
                    return rs;

       
                //发送并等待处理
                SendAndWait(orderlst);
                #region 指令都执行完了

                for (int j = 0; j < orderlst.Count; j++)
                {
                    //Application.DoEvents();
                    Analysis62056.TProtocol62056 anaptl = (Analysis62056.TProtocol62056)orderlst[j].AnaPtl;
                    int doflag = orderlst[j].SendFlag == CommConst.CommFlag.CommSuccess ? 1 : -1;
                    rs = doflag;
                    TestMeter ameter = (TestMeter)orderlst[j].meterObj;
                    try
                    {                                             
                        ameter.Meter62056.SendCount = anaptl.SSS; //hxh 两条都不能省，底层解析后可能自动生成应用层续抄，改变了发送计数
                        ameter.Meter62056.RecCount = anaptl.RRR;   //接收本来就需传出                   
                    }
                    catch
                    { }
                    
                    //处理解析后的特殊处理函数  没有错误的情况下才执行  shaunwang 2016-12-7
                    if (doflag > 0 && !string.IsNullOrEmpty(anaptl.ptlinfo.AnaFunc))
                    {
                        List<ProObAttr> AttrLst = ameter.ObAttrLst;

                        //hxh 2017-3-21  每次执行解析后的函数只传对应的对象,不传所有对象. 否则在多项抄读时元素方案会错位更新
                        List<CosemObject> OILst = anaptl.ptlformat.Apdu.OIList;
                        for (int m = 0; m < AttrLst.Count; m++)
                        {
                            //Application.DoEvents();
                            if (string.IsNullOrEmpty(AttrLst[m].AnaFunc)) 
                                continue;

                            string[] funclst = AttrLst[m].AnaFunc.Split(';');
                            
                            for (int f = 0; f < funclst.Length; f++)
                            {
                                string errinfo = string.Empty;
                                if (string.IsNullOrEmpty(funclst[f]))
                                    continue;
                                PubFunc62056.FuncAfterAna(ameter.Meter62056, funclst[f], AttrLst[m], OILst[m], OILst, ref errinfo);
                                orderlst[j].errorinfo += errinfo;

                               // if (NextFramePosted != null)                              
                               //     NextFramePosted(orderlst[j].meterObj, anaptl, rwflag, rwtype, doflag, orderlst[j].errorinfo);


                                //if (!StopReading && AttrLst[m].ParNumber >= 1) //hxh 2017-6-15
                                //{
                                //    TestMeter copyMeter = (orderlst[j].meterObj as TestMeter).Copy();

                                //    List<TestMeter> copymeterlst = new List<TestMeter>();
                                //    copymeterlst.Add(copyMeter);

                                //    rs = RWOneDataFromObAttr(copymeterlst, RorW, rwflag, rwtype, scflag, timetag, ShowUI, NextFramePosted);//
                                //    if (rs < 0)
                                //        return rs;
                                //}                             
                            }
                        }                    
                        
                    }
                    if (NextFramePosted != null)  //hxh 2018-10-22 因解析后函数里可能会做某些处理,因此放在解析后函数处理之后显示
                        NextFramePosted(ameter, anaptl, rwflag, rwtype, doflag, orderlst[j].errorinfo);


                    TimeSpan dt = DateTime.Now - orderlst[j].createtime;
                    //MessageBox.Show("耗时:" + dt.TotalMilliseconds);
                }
                #endregion
            }
            finally
            {
                //CloseComm();
                //GC.Collect();
            }
            return rs;
        }


        /// <summary>
        /// 处理主动上传数据
        /// </summary>
        /// <param name="meterlst">表计列表</param>
        /// <param name="NextFramePosted"></param>
        /// <returns></returns>
        //public int DoListen(List<TestMeter> meterlst, ClientApduSel rwflag, string rwtype, DoAfterListen NextFramePosted)
        //{
        //    int rs = 1;
        //    try
        //    {
        //        if (meterlst.Count == 0)
        //            return rs;
        //        this.MeterLst = meterlst;
        //        //操作方式显示

        //        List<CommConst.TOrdertype> orderlst = new List<CommConst.TOrdertype>();
        //        #region 生成指令部分
        //        for (int m = 0; m < meterlst.Count; m++)
        //        {
        //            //Application.DoEvents();
        //            Thread.Sleep(1);
        //            TestMeter ameter = meterlst[m];
        //            //实例化一个指令类
        //            CommConst.TOrdertype neworder = new CommConst.TOrdertype();

        //            neworder.ptltype = (int)PtlType.IEC62056;
        //            //下面给neworder赋值
        //            string errorinfo = string.Empty;

        //            List<ProObAttr> AttrLst = ameter.ObAttrLst;
                    
        //            Analysis62056.TProtocol62056 anaptl = PubFunc62056.CreateAnaPtl(ameter.Meter62056, AttrLst, rwflag, rwtype, ref errorinfo);  //用于解析
        //            if (errorinfo != string.Empty)
        //            {
        //                errorinfo = "生成解析类失败:" + errorinfo;

        //                if (NextFramePosted != null)
        //                    NextFramePosted(ameter, anaptl, -1, errorinfo);
        //                neworder.Fail(false, errorinfo);
        //                ameter.ErrInfo = errorinfo;
        //                continue;
        //            }

        //            try
        //            {
        //                neworder.meterObj = ameter;  //
        //                neworder.fmeterid = ameter.MeterID;
        //                neworder.address = ameter.MeterCommAddr;
        //                neworder.MeterSNo = ameter.SNO;  //表位
        //                neworder.MACAddr = ameter.CommInfo.MACAddr;
        //                neworder.AnaPtl = anaptl;

        //                if (string.IsNullOrEmpty(ameter.Meter62056.udpCAddr)) //47协议UDP模式时无法取合法帧
        //                    neworder.GetCorrectFrame = GetCorrectFrame();
        //                neworder.DoAfterAnalysis = DoAfterAnalysis; 

        //                orderlst.Add(neworder);
        //            }
        //            catch (Exception ex)
        //            {
        //                errorinfo = "生成指令失败:" + ex;

        //                if (NextFramePosted != null)
        //                    NextFramePosted(ameter, anaptl, -1, errorinfo);
        //                neworder.Fail(false, errorinfo);
        //                ameter.ErrInfo = errorinfo;
        //                continue;
        //            }
        //        }
        //        #endregion

        //        //监听上传数据并处理
        //        StartListen(orderlst, NextFramePosted);
        //    }
        //    finally
        //    {
        //        //CloseComm();
        //        //GC.Collect();
        //    }
        //    return rs;

        //}


        /// <summary>
        /// 发送指令  需要返回
        /// </summary>
        /// <param name="meterlst">表计列表</param>
        /// <param name="ShowUI">是否需要在界面显示</param>
        /// <returns></returns>
        public int RWRandomDataWithAPDU(List<TestMeter> meterlst, List<string> OrderLst, bool ShowUI, NextFramePostedDelegate NextFramePosted)
        {
            return RWRandomDataWithAPDU(meterlst, OrderLst, ShowUI, true, NextFramePosted);
        }

        /// <summary>
        /// 发送指令
        /// </summary>
        /// <param name="meterlst">表计列表</param>
        /// <param name="ShowUI">是否需要在界面显示</param>
        /// <returns></returns>
        public int RWRandomDataWithAPDU(List<TestMeter> meterlst, List<string> OrderLst, bool ShowUI, bool needReturn, NextFramePostedDelegate NextFramePosted)
        {
            int rs = 1;
            try
            {
                if (meterlst.Count == 0)
                    return rs;
                this.MeterLst = meterlst;

                //生成指令并发送


                List<CommConst.TOrdertype> orderlst = new List<CommConst.TOrdertype>();
                #region 生成指令部分
                for (int m = 0; m < meterlst.Count; m++)
                {
                    //Application.DoEvents();
                    //Thread.Sleep(1);
                    Task.Delay(1).Wait();
                    TestMeter ameter = meterlst[m];
                    //实例化一个指令类
                    CommConst.TOrdertype neworder = new CommConst.TOrdertype();

                    neworder.ptltype = (int)PtlType.IEC62056;
                    //下面给neworder赋值
                    string errorinfo = string.Empty;
                    Analysis62056.TProtocol62056 anaptl = new Analysis62056.TProtocol62056();
                    anaptl.ptlformat.C.RRR = ameter.Meter62056.RecCount;  //接收计数器
                    anaptl.ptlformat.C.SSS = ameter.Meter62056.SendCount;  //发送计数器
                    try
                    {
                        neworder.OrderName = "任意命令";

                        errorinfo = string.Empty;
                        string orderstr = OrderLst[m];

                        neworder.orderlst = new List<string>(orderstr.Split(','));

                        if (neworder.orderlst == null || neworder.orderlst.Count == 0)
                        {
                            errorinfo = "没有指令要发送";

                            if (NextFramePosted != null && ShowUI)
                                NextFramePosted(ameter, null, ClientApduSel.GETRequest, null, -1, errorinfo);
                            neworder.Fail(false, errorinfo);
                            continue;
                        }
                        neworder.realorder = neworder.orderlst[0];
                        neworder.order = neworder.realorder;
                        neworder.meterObj = ameter;  //
                        neworder.fmeterid = ameter.MeterID;
                        neworder.waitreturn = needReturn;

                        //预连接角色不需要返回
                        if (PubFunc62056.CheckPreConnClient(ameter.Meter62056.MTRole.RoleClientAddr))
                            neworder.waitreturn = false;

                        neworder.MeterSNo = ameter.SNO;  //表位  
                        neworder.MACAddr = ameter.CommInfo.MACAddr;
                        neworder.AnaPtl = anaptl;
                        neworder.NeedAna = true;  //////

                        neworder.GetCorrectFrame = GetCorrectFrame();

                        neworder.order = CommManager.GetWakeChar() + neworder.order + CommManager.GetDelayChar();  //增加前导符
                        neworder.DoAfterAnalysis = DoAfterAnalysis;

                        orderlst.Add(neworder);
                    }
                    catch (Exception ex)
                    {
                        errorinfo = "准备指令失败:" + ex;

                        if (NextFramePosted != null && ShowUI)
                            NextFramePosted(ameter, null, ClientApduSel.GETRequest, null, -1, errorinfo);
                        neworder.Fail(false, errorinfo);
                        continue;
                    }

                }
                #endregion

                //发送并等待处理
                SendAndWait(orderlst);


                #region 指令都执行完了

                for (int j = 0; j < orderlst.Count; j++)
                {
                    //Application.DoEvents();
                    Analysis62056.TProtocol62056 anaptl = (Analysis62056.TProtocol62056)orderlst[j].AnaPtl;
                    int doflag = orderlst[j].SendFlag == CommConst.CommFlag.CommSuccess ? 1 : -1;
                    TestMeter ameter = (TestMeter)orderlst[j].meterObj;
                    try
                    {                        
                        ameter.Meter62056.SendCount = anaptl.SSS;
                        ameter.Meter62056.RecCount = anaptl.RRR;  //hxh 解析完后把计数器返回表                     
                    }
                    catch
                    { }

                    if (NextFramePosted != null)
                        NextFramePosted(ameter, anaptl, ClientApduSel.GETRequest, orderlst[j].recstr, doflag, orderlst[j].errorinfo);

                    TimeSpan dt = DateTime.Now - orderlst[j].createtime;
                    //MessageBox.Show("耗时:" + dt.TotalMilliseconds);
                }
                #endregion
            }
            finally
            {
                //CloseComm();
                GC.Collect();
            }
            return rs;
        }
        /// <summary>
        /// 指令解析后的处理 hxh 2018-5-28
        /// </summary>
        /// <param name="?"></param>
        private void DoAfterAnalysis(CommConst.TOrdertype aorder)
        {
            Analysis62056.TProtocol62056 anaptl = (Analysis62056.TProtocol62056)aorder.AnaPtl;

            string realdata = anaptl.GetRealData();
            if (!string.IsNullOrEmpty(realdata) && realdata.Length <= 1000)
                aorder.orderinfo = "解密后或分帧合总后纯数据:"
                                 + PubFunction.SplitStr(realdata);
            else
                aorder.orderinfo = string.Empty;
        }

        /// <summary>
        /// 刷新各表位对应串口的波特率
        /// </summary>
        /// <param name="meterlst"></param>
        public void RefreshBaudRate(List<TestMeter> meterlst)
        {
            //for (int i = 0; i < meterlst.Count; i++)
            //{
            //    SetCommMode(meterlst[i]);
            //    if (meterlst[i].commMode != CommConst.CommMode.RS232)
            //        return;
            //    string newBaudRate = meterlst[i].PnNode.SettingValue;
            //    try
            //    {
            //        int result = CommControl.RefreshBaudRate(meterlst[i].MeterPort, Convert.ToInt16(newBaudRate));
            //        if (result < 0)
            //            meterlst[i].PnNode.ErrorInfo = "刷新波特率失败";
            //    }
            //    catch
            //    {
            //        meterlst[i].PnNode.ErrorInfo = "刷新波特率失败";
            //    }
            //}

        }

        

      //  /// <summary>
      //  /// 通配地址读表地址 hxh 2017-5-5
      //  /// </summary>
      //  /// <param name="errinfo"></param>
      //  /// <returns></returns>
      //  public int ReadAddrInfo(List<TestMeter> meterlst, ref string errinfo)
      //  {
      //      int rs = 1;
      //      try
      //      {
      //          //生成要读取对象的列表
      //          List<ProObAttr> AttrLst = new List<ProObAttr>();             
               
      //          ProObAttr tmpObAttr = ProObAttr.GetAttrByOAD(PtlConsts.AddrOAD, AttrType.属性.ToString());
      //          if (tmpObAttr != null)
      //          {
      //              tmpObAttr.eleseq = "00";
      //              AttrLst.Add(tmpObAttr);
      //          }

      //          for (int m = 0; m < meterlst.Count; m++)
      //          {
      //              Application.DoEvents();

      //              meterlst[m].ObAttrLst = AttrLst;
      //              meterlst[m].SecurityMode = 0;  
      //              meterlst[m].MeterCommAddr="AAAAAAAAAAAA"; //使用12位通配符
      //          }
      //          StopOperating(false);
      //          NextFramePostedDelegate NextFramePosted = new NextFramePostedDelegate(DoAfterReadAddr);
      //          rs = RWOneDataFromObAttr(meterlst, "R", ClientApduSel.GETRequest, GetRRMode.GetNormal.ToString(),0, "00",true, NextFramePosted);

      //      }
      //      catch (Exception ex)
      //      {
      //          errinfo = ex.Message;
      //          rs = -1;
      //      }
      //      return rs;
      //  }

      //  private void DoAfterReadAddr(object testMeter, object anaPtl,ClientApduSel rwflag, string rwtype, string errinfo)
      //  {
      //      Analysis62056.TProtocol62056 orderptl = (Analysis62056.TProtocol62056)anaPtl;
      //      TestMeter resmeter = (TestMeter)testMeter;
      //      if (string.IsNullOrEmpty(errinfo))
      //      {
      //          List<OIObject> OILst = orderptl.ptlformat.Apdu.clientApdu.OIList;
      //          for (int i = 0; i < OILst.Count; i++)
      //          {
      //              ElementData eleobj = OILst[i].eleNodeList[0];  //取对象的第一个属性
      //              resmeter.MeterCommAddr = eleobj.ReadValue;
      //          }
      //      }
      //      else
      //          resmeter.MeterCommAddr = errinfo;
      //  }
      ////  #endregion
      //  /// <summary>
      //  /// hxh 2017-5-5
      //  /// </summary>
      //  /// <param name="errinfo"></param>
      //  /// <returns></returns>
      //  public int ReadMeterNOInfo(List<TestMeter> meterlst, ref string errinfo)
      //  {
      //      int rs = 1;
      //      try
      //      {
      //          //生成要读取对象的列表
      //          List<ProObAttr> AttrLst = new List<ProObAttr>();

      //          ProObAttr tmpObAttr = ProObAttr.GetAttrByOAD(PtlConsts.MeterNoOAD, AttrType.属性.ToString());
      //          if (tmpObAttr != null)
      //          {
      //              tmpObAttr.eleseq = "00";
      //              AttrLst.Add(tmpObAttr);
      //          }

      //          for (int m = 0; m < meterlst.Count; m++)
      //          {
      //              Application.DoEvents();

      //              meterlst[m].ObAttrLst = AttrLst;
      //              meterlst[m].SecurityMode = 0;
                   
      //          }
      //          StopOperating(false);
      //          NextFramePostedDelegate NextFramePosted = new NextFramePostedDelegate(DoAfterReadMeterNO);
      //          rs = RWOneDataFromObAttr(meterlst, "R", ClientApduSel.GETRequest, GetRRMode.GetNormal.ToString(), 0, "00", true, NextFramePosted);

      //      }
      //      catch (Exception ex)
      //      {
      //          errinfo = ex.Message;
      //          rs = -1;
      //      }
      //      return rs;
      //  }

      //  private void DoAfterReadMeterNO(object testMeter, object anaPtl, ClientApduSel rwflag, string rwtype, string errinfo)
      //  {
      //      Analysis62056.TProtocol62056 orderptl = (Analysis62056.TProtocol62056)anaPtl;
      //      TestMeter resmeter = (TestMeter)testMeter;
      //      if (string.IsNullOrEmpty(errinfo))
      //      {
      //          List<OIObject> OILst = orderptl.ptlformat.Apdu.clientApdu.OIList;
      //          for (int i = 0; i < OILst.Count; i++)
      //          {
      //              ElementData eleobj = OILst[i].eleNodeList[0];  //取对象的第一个属性
      //              resmeter.MeterNO = eleobj.ReadValue;
      //          }
      //      }
      //      else
      //          resmeter.MeterNO = errinfo;
      //  }

        /// <summary>
        /// 设置表地址 
        /// </summary>
        /// <param name="errinfo"></param>
        /// <returns></returns>
        public int SetAddrInfo(List<TestMeter> meterlst,string newAddr, ref string errinfo)
        {
            int rs = 1;
            try
            {
                ProObAttr tmpObAttr = ProObAttr.GetAttrByCAD(PtlConsts.AddrCAD, AttrType.属性.ToString());
                if (tmpObAttr != null)
                {                   
                    for (int m = 0; m < meterlst.Count; m++)
                    {
                        //Application.DoEvents();
                        //生成要读取对象的列表
                        List<ProObAttr> AttrLst = new List<ProObAttr>();
                        tmpObAttr.inputValue = newAddr;                        
                        AttrLst.Add(tmpObAttr);
                        meterlst[m].ObAttrLst = AttrLst;                       
                    }
                }
                StopOperating(false);
                //NextFramePostedDelegate NextFramePosted = new NextFramePostedDelegate(DoAfterSetAddr);
                rs = RWOneDataFromObAttr(meterlst, EnuFrameType.I, ClientApduSel.SETRequest, SetRRMode.SetNormal.ToString(), true, null);

            }
            catch (Exception ex)
            {
                errinfo = ex.Message;
                rs = -1;
            }
            return rs;
        }

        //private void DoAfterSetAddr(object testMeter, object anaPtl, ClientApduSel rwflag, string rwtype, int doflag, string errinfo)
        //{
            //Analysis62056.TProtocol62056 orderptl = (Analysis62056.TProtocol62056)anaPtl;
            //TestMeter resmeter = (TestMeter)testMeter;
            //if (string.IsNullOrEmpty(errinfo))
            //{
            //    List<OIObject> OILst = orderptl.ptlformat.Apdu.OIList;
            //    for (int i = 0; i < OILst.Count; i++)
            //    {
            //        ElementData eleobj = OILst[i].eleNodeList[0];  //取对象的第一个属性
            //        resmeter.MeterCommAddr = eleobj.SetValue;
            //    }
            //}
            //else
            //    resmeter.MeterCommAddr = errinfo;
        //}
        //  #endregion




    }
}
